/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package Controle;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ListIterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import Dados.*;




/**
 *
 * @author ra071677
 */
//Classe Singleton
public class Controle
{
    private static Controle m_instance;    
    private ArrayList<UsuarioCadastrado> m_lUsuarios;
    private ArrayList<Avaliador> m_lAvaliadores;
    private ArrayList<String> m_lEmailsAvaliadores;
    private ArrayList<String> m_lEmailsOrganizadores;

    private UsuarioCadastrado usuarioAtual;


    public static boolean verificaExtensao(String justFileName)
    {
        if(!justFileName.equals(""))
        {
            String extensao = justFileName.substring(justFileName.length()-3, justFileName.length());
            boolean result =  extensao.equals("pdf");
            return result;
        }
        else
        {
            return false;
        }
    }

    public void setUsuarioAtual(UsuarioCadastrado usuarioAtual)
    {
        this.usuarioAtual = usuarioAtual;
    }

    public UsuarioCadastrado getUsuarioAtual()
    {
        return this.usuarioAtual;
    }


    //Constructor
    private Controle()
    {
        m_lUsuarios = new ArrayList<UsuarioCadastrado>();
        m_lEmailsAvaliadores = new ArrayList<String>();
        m_lEmailsOrganizadores = new ArrayList<String>();
        m_lAvaliadores = new ArrayList<Avaliador>();
        setUsuarioAtual(null);


        leLinhas(Controle.class.getResource("avaliadores").toString(), m_lEmailsAvaliadores);
        leLinhas(Controle.class.getResource("organizadores").toString(), m_lEmailsOrganizadores);
        LeUsuarios(Controle.class.getResource("usuarios").toString());
        /**@TODO
         * Lêr as infos dos artigosSubmetidos e carregar na ArrayList m_lArtigos, assim como instanciar os artigos
         * e fazer os usuarios referenciarem seus respectivos infos de artigos,
         * entao descomentar linha 119 e remover linha 118 de AreaCadastrado.java
         *
         * Criar um arquivo para armazenar index (index eh a variavel usada na criacao de artigos)
         *
         */

    }

    /**
     * Escreve a String 'linha' no arquivo dado pelo 'caminho'
     * @param linha String a ser escrita
     * @param caminho Caminho onde a 'linha' serah escrita
     */
    private void EscreveLinha(String linha, String caminho)
    {
        try
        {
            File file = new File(new URL(caminho).getFile());
           
            try
            {
                FileWriter writer = new FileWriter(file, true);
                writer.write(linha);
                writer.close();
            }
            catch (IOException ex)
            {
                Logger.getLogger(Controle.class.getName()).log(Level.SEVERE, null, ex);
            }

        }
        catch (MalformedURLException ex)
        {
            Logger.getLogger(Controle.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Le os usuarios cadastrados em 'caminho' e os retorna em uma ArrayList
     * @param caminho caminho do arquivo a ser lido
     * @return Retorna uma ArrayList<String> de todos os usuarios cadastrados
     */
    private int LeUsuarios(String caminho)
    {
        ArrayList usuarios = new ArrayList<String>();

        int nUsuarios = leLinhas(Controle.class.getResource("usuarios").toString(), usuarios);
        Iterator <String> it = usuarios.iterator();
        while(it.hasNext())
        {
            String RegistroAtual = it.next();
            String[] tokenizado = RegistroAtual.split(";");
            String Nome = tokenizado[0];
            String Endereco = tokenizado[1];
            String Email = tokenizado[2];
            String RG = tokenizado[3];
            String CPF = tokenizado[4];
            String Senha = tokenizado[5];        
            EfetuarCadastro(Nome, Endereco, Email, RG, CPF, Senha);
        }

        return nUsuarios;
    }

    /**
     * Le as linhas do arquivo em 'caminho' e os armazena linha por linha na ArrayList<String> 'destino'
     * @param caminho Caminho do arquivo a ser lido
     * @param destino ArrayList<String> onde serao armazenadas as linhas
     * @return Retorna o numero de linhas do arquivo em 'caminho'
     */
    static public int leLinhas(String caminho, ArrayList destino)
    {
        int nRegistros = 0;
        BufferedReader origem = null;
        URL url = null;
        try
        {
            url = new URL(caminho);
        }
        catch (MalformedURLException ex)
        {
            Logger.getLogger(Controle.class.getName()).log(Level.SEVERE, null, ex);
        }
        try 
        {
            origem = new BufferedReader(new InputStreamReader(url.openStream()));
        }
        catch (IOException ex)
        {
            Logger.getLogger(Controle.class.getName()).log(Level.SEVERE, null, ex);
        }


        if(origem!=null)
        {
            String temp = null;
            try
            {
                temp = origem.readLine();
            }
            catch (IOException ex)
            {
                Logger.getLogger(Controle.class.getName()).log(Level.SEVERE, null, ex);
            }
            while(temp != null && !temp.equals(""))
            {
                nRegistros++;
                destino.add(temp);
                try 
                {
                    temp = origem.readLine();
                }
                catch (IOException ex)
                {
                    Logger.getLogger(Controle.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }

        return nRegistros;
    }

    static public Controle GetInstance()
    {
        if(m_instance == null)
        {
            m_instance = new Controle();
        }
        return m_instance;
    }

    public ArrayList<UsuarioCadastrado> GetUsers()
    {
        return m_lUsuarios;
    }

    public ArrayList<Avaliador> GetAppraisers()
    {
        return m_lAvaliadores;
    }

    public ArrayList<String> GetAppraisersMails()
    {
        return m_lEmailsAvaliadores;
    }

    public ArrayList<String> GetOrganizersMails()
    {
        return m_lEmailsOrganizadores;
    }

    public boolean VerificarCampos(
            String nome,
            String endereco,
            String email,
            String rg,
            String cpf,
            String senha)
    {
        return    
            (nome != null) && (! nome.isEmpty()) &&
            (endereco != null) && (! endereco.isEmpty()) &&
            (email != null) && (! email.isEmpty()) &&
            (rg != null) && (! rg.isEmpty()) &&
            (cpf != null) && (! cpf.isEmpty()) &&
            (senha != null) && (! senha.isEmpty()) &&
            (email.contains("@"));
    }

    public String EfetuarCadastro(
            String nome,
            String endereco,
            String email,
            String rg,
            String cpf,
            String senha
            )
    {
        if (VerificarCampos(nome, endereco, email, rg, cpf, senha) == false)
        {
            return "dadosInconsistentes";
        } 
        else if(JaCadastrado(cpf, email))
        {
            return "usuarioJaCadastrado";
        } 
        else
        {
            UsuarioCadastrado novo = null;
            String areaRetorno = null;

            if (m_lEmailsAvaliadores.contains(email))
            {
                Avaliador novoLista = new Avaliador(nome, endereco, email, rg, cpf, senha, "Area de conhecimento");
                m_lAvaliadores.add(novoLista);
                novo = novoLista;
                areaRetorno = Constantes.AREA_AVALIADOR;
            } else if (m_lEmailsOrganizadores.contains(email))
            {
                novo = new Organizador(nome, endereco, email, rg, cpf, senha, "Funcao");
                areaRetorno = Constantes.AREA_ORGANIZADOR;
            } else {
                novo = new UsuarioCadastrado(nome, endereco, email, rg, cpf, senha);
                areaRetorno = Constantes.AREA_SUBMISSAO;
            }

            m_lUsuarios.add(novo);
            //String linha = nome+";"+endereco+";"+email+";"+rg+";"+cpf+";"+senha+";";
            //EscreveLinha(linha, Controle.class.getResource("usuarios").toString());

            setUsuarioAtual(novo);
            return areaRetorno;
        }
    }

    public ArrayList ExibirAbas(String Email)
    {
        return null;
    }

    /**
     * Dado um String 'cpf' e um String 'e-mail', busca na ArrayList de usuarios se jah existe
     * @param Cpf CPF a ser verificado
     * @param Email E-mail a ser verficado
     * @return Retorna true caso ja esteja cadastrado
     */
    public boolean JaCadastrado(String Cpf, String Email)
    {
        Iterator <UsuarioCadastrado> it= m_lUsuarios.iterator();
        while(it.hasNext())
        {
            UsuarioCadastrado temp = it.next();
            if(temp.GetCpf().equals(Cpf) || temp.GetEmail().equals(Email))
            {
                return true;
            }
        }
        return false;
    }

    /**
     * Dado um e-mail e senha, verifica se existe na ArrayListe de usuarios e retorna o tipo do usuario
     * @param login Login do usuario
     * @param senha Senha do usuario
     * @return Retorna o tipo do usuario (String) (avaliador, organizador, usuarioCadastrado)
     */
    public String VerificaLogin(String login, String senha)
    {
        Iterator <UsuarioCadastrado> itUser= m_lUsuarios.iterator();       

        // Primeiro Verifica se o usuario esta cadastrado...
        while(itUser.hasNext())
        {
            UsuarioCadastrado temp = itUser.next();
            if (temp.GetEmail().equals(login) && temp.GetSenha().equals(senha))
            {
                //uma vez encontrado o usuario
                setUsuarioAtual(temp);
                return getTipoUsuario(login);
            }
        }
        return "";
    }

    public boolean VerificaExtensao(int Artigo)
    {
        return false;
    }

    /**
     * 
     * @param email
     * @param titulo
     * @param assunto
     * @return
     */
    public void SubmeterArtigo(String email, String titulo, String assunto)
    {
        UsuarioCadastrado user = BuscaCadastro(email);
        user.SubmeterArtigo(titulo, assunto);
        
        //Artigo novoArtigo = user.getArtigo();
        //String linha = novoArtigo.toString();
        //EscreveLinha(linha, Controle.class.getResource("artigos").toString());
        
    }

    public UsuarioCadastrado BuscaCadastro(String email) {
        UsuarioCadastrado user = null;
        ListIterator<UsuarioCadastrado> userIt = m_lUsuarios.listIterator();

        user = userIt.next();
        while ((userIt.hasNext()) && (! user.GetEmail().equals(email)))
        {
            user=userIt.next();
        }
        
        return user;
    }

    public ArrayList ExibirArtigos(String Email)
    {
        return null;
    }
    
    public void SubmeterAvaliacao(String Email, int IdArtigo, float Nota, String Comentario)
    {
    }

    /**
     * Dado um login retorna o tipo do usuario atraves de busca nas ArrayList's de avaliador e organizador
     * @param login Login a buscar nas ArrayLists<String>'s
     * @return Retorna o tipo do usuario (String) (avaliador, organizador, usuarioCadastrado)
     */
    private String getTipoUsuario(String login)
    {
        String areaRetorno = null;

        if (m_lEmailsAvaliadores.contains(login)) {
            areaRetorno = Constantes.AREA_AVALIADOR;
        }
        else if (m_lEmailsOrganizadores.contains(login)) {
            areaRetorno = Constantes.AREA_ORGANIZADOR;
        } else {
            areaRetorno = Constantes.AREA_SUBMISSAO;
        }

        return areaRetorno;
    }

    public void distribuirArtigos() {

        UsuarioCadastrado user = null;
        Avaliador aval = null;
        ListIterator<UsuarioCadastrado> userIt = m_lUsuarios.listIterator();
        ListIterator<Avaliador> avalIt = m_lAvaliadores.listIterator();

        if(m_lAvaliadores.isEmpty()) return;

        if (avalIt.hasNext())
            aval = avalIt.next();

        while (userIt.hasNext())
        {
            user = userIt.next();

            if ((user.getArtigo() != null) && (aval != null)) {
                aval.inserirArtigo(user.getArtigo());
                
                if (! avalIt.hasNext()) {
                    avalIt = m_lAvaliadores.listIterator(0);
                }

                aval = avalIt.next();
                
            }
        }
    }


}